package com.young.scrollchildanim;

import android.animation.ArgbEvaluator;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
 * Author：young
 * .
 * Time： 2022/5/7 9:43 周六
 * .
 * Desc：用于包裹普通子视图来完成动画的视图（偷梁换柱）
 */
public class ScrollChildMountAnimView extends FrameLayout implements ScrollAnimMountCallback {

    /**
     * <attr name="mount_anim_translation">
     * <flag name="fromTop" value="0x01" />
     * <flag name="fromBottom" value="0x02" />
     * <flag name="fromLeft" value="0x04" />
     * <flag name="fromRight" value="0x08" />
     * </attr>
     * 0000000001
     * 0000000010
     * 0000000100
     * 0000001000
     * <p>
     * <p>
     * 0000000101
     */
    // 位移动画
    private static final int TRANSLATION_FROM_TOP = 0x01;// 从上面进入
    private static final int TRANSLATION_FROM_BOTTOM = 0x02;// 从底部进入
    private static final int TRANSLATION_FROM_LEFT = 0x04;// 从左边进入
    private static final int TRANSLATION_FROM_RIGHT = 0x08;// 从右边进入

    private ArgbEvaluator argbEvaluator = new ArgbEvaluator();// argb插值器

    /**
     * 自定义属性的一些接收的变量
     */
    private int mountAnimFromBgColor;//背景颜色变化开始值
    private int mountAnimToBgColor;//背景颜色变化结束值
    private boolean isMountAnimAlpha;//是否需要透明度动画
    private int mountAnimTranslation;//平移值
    private boolean isMountAnimScaleX;//是否需要x轴方向缩放
    private boolean isMountAnimScaleY;//是否需要y轴方向缩放
    private int currentHeight;//本view的高度
    private int currentWidth;//宽度

    public ScrollChildMountAnimView(@NonNull Context context) {
        super(context);
    }

    public ScrollChildMountAnimView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ScrollChildMountAnimView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public ScrollChildMountAnimView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    /**
     * 当视图的大小发生变化时，在布局期间调用。如果你刚刚被添加到视图层次结构中，你被调用时的旧值为0。
     *
     * @param w    当前的视图宽度
     * @param h    当前视图的高度
     * @param oldw 当前视图旧的宽度
     * @param oldh 当前视图旧的高度
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        currentWidth = w;
        currentHeight = h;
        onChildAnimUnmount();
    }

    @Override
    public void onChildAnimMount(float ratio) {
        // 执行视图动画
        // ratio:0~1
        //控制自身的动画属性
        if (isMountAnimAlpha) {
            setAlpha(ratio);
        }
        if (isMountAnimScaleX) {
            setScaleX(ratio);
        }
        if (isMountAnimScaleY) {
            setScaleY(ratio);
        }

        //判断到底是哪一种值：fromTop,fromBottom,fromLeft,fromRight
        if (isMountAnimFrom(TRANSLATION_FROM_BOTTOM)) {
            setTranslationY(currentHeight * (1 - ratio)); // currentHeight ---> 0 代表原来的位置
        }
        if (isMountAnimFrom(TRANSLATION_FROM_TOP)) {
            setTranslationY(-currentHeight * (1 - ratio)); // -currentHeight ---> 0 代表原来的位置
        }
        if (isMountAnimFrom(TRANSLATION_FROM_LEFT)) {
            setTranslationX(currentWidth * (1 - ratio));// currentWidth ---> 0 代表原来的位置
        }
        if (isMountAnimFrom(TRANSLATION_FROM_RIGHT)) {
            setTranslationX(-currentWidth * (1 - ratio));// -currentWidth ---> 0 代表原来的位置
        }

        // 颜色渐变动画
        if (mountAnimFromBgColor != -1 && mountAnimToBgColor != -1) {
            //ratio=0.5 color=中间颜色
            setBackgroundColor((Integer) argbEvaluator.evaluate(ratio, mountAnimFromBgColor, mountAnimToBgColor));
        }
    }

    @Override
    public void onChildAnimUnmount() {
        // 恢复视图
        if (isMountAnimAlpha) {
            setAlpha(0);
        }
        if (isMountAnimScaleX) {
            setScaleX(0);
        }
        if (isMountAnimScaleY) {
            setScaleY(0);
        }

        //判断到底是哪一种值：fromTop,fromBottom,fromLeft,fromRight
        if (isMountAnimFrom(TRANSLATION_FROM_BOTTOM)) {
            setTranslationY(currentHeight); // currentHeight ---> 0 代表原来的位置
        }
        if (isMountAnimFrom(TRANSLATION_FROM_TOP)) {
            setTranslationY(-currentHeight); // -currentHeight ---> 0 代表原来的位置
        }
        if (isMountAnimFrom(TRANSLATION_FROM_LEFT)) {
            setTranslationX(currentWidth);// currentWidth ---> 0 代表原来的位置
        }
        if (isMountAnimFrom(TRANSLATION_FROM_RIGHT)) {
            setTranslationX(-currentWidth);// -currentWidth ---> 0 代表原来的位置
        }
    }

    /**
     * 判断动画的平移方向
     *
     * @param translationMask 动画配置的方向
     * @return true: 是传入的动画方向 false：不是传入的动画方向
     */
    private boolean isMountAnimFrom(int translationMask) {
        if (mountAnimTranslation == -1) {
            return false;
        }
        //fromLeft|fromBottom & fromBottom = fromBottom
        return (mountAnimTranslation & translationMask) == translationMask;
    }

    public void setMountAnimFromBgColor(int mountAnimFromBgColor) {
        this.mountAnimFromBgColor = mountAnimFromBgColor;
    }

    public void setMountAnimToBgColor(int mountAnimToBgColor) {
        this.mountAnimToBgColor = mountAnimToBgColor;
    }

    public void setMountAnimAlpha(boolean mountAnimAlpha) {
        isMountAnimAlpha = mountAnimAlpha;
    }

    public void setMountAnimTranslation(int mountAnimTranslation) {
        this.mountAnimTranslation = mountAnimTranslation;
    }

    public void setMountAnimScaleX(boolean mountAnimScaleX) {
        isMountAnimScaleX = mountAnimScaleX;
    }

    public void setMountAnimScaleY(boolean mountAnimScaleY) {
        isMountAnimScaleY = mountAnimScaleY;
    }
}
